﻿using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.IdentityModel.Logging;

using PLCS.App.Shared.Events;
using PLCS.Application.Contracts.EquipmentApp.Dtos;
using PLCS.Client.Service.Client;
using PLCS.Domain.Shared.Enums;
using PLCS.Shared.Common.Constant;

using RestSharp;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace PLCS.App.Shared.Views.UserControls.Chlidren;

/// <summary>
/// 输送线
/// </summary>
public partial class ConveyorLine : UserControl
{
    #region Properties

    //托盘或货物
    private Rectangle goods = new();

    //左右上下侧边框
    public Rectangle leftline = new();

    public Rectangle rightline = new();
    public Rectangle topline = new();
    public Rectangle bottomline = new();

    //Webapi客户端
    public HttpRestClient restClient = new();

    private RequestParam requestParam;
    public SolidColorBrush bg;

    //竖放标志
    private bool verticalflag;

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(ConveyorLine), new UIPropertyMetadata(null));

    public object CommandParameter
    {
        get { return (object)GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandParameter.  This enables animation,styling,binding,etc...
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(ConveyorLine), new UIPropertyMetadata(null));

    /// <summary>
    /// 强制输入事件和属性来自FrameworkElement
    /// </summary>
    public IInputElement CommandTarget
    {
        get { return (IInputElement)GetValue(CommandTargetProperty); }
        set { SetValue(CommandTargetProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandTarget.  This enables animation,etc...
    public static readonly DependencyProperty CommandTargetProperty =
        DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(ConveyorLine), new UIPropertyMetadata(null));

    /// <summary>
    /// 名称
    /// </summary>
    public string SName
    {
        get { return (string)GetValue(SNameProperty); }
        set { SetValue(SNameProperty, value); }
    }

    public static readonly DependencyProperty SNameProperty =
        DependencyProperty.Register("SName", typeof(string), typeof(ConveyorLine), new PropertyMetadata("S101"));

    //名称改变
    //private static void OnSNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as ConveyorLine).RefreshHaveStatus();
    /// <summary>
    /// 是否有无托盘
    /// </summary>
    public YesNo HaveStatus
    {
        get { return (YesNo)GetValue(HaveStatusProperty); }
        set { SetValue(HaveStatusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Seat.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HaveStatusProperty =
        DependencyProperty.Register("HaveStatus", typeof(YesNo), typeof(ConveyorLine), new PropertyMetadata(YesNo.否, new PropertyChangedCallback(OnHaveChanged)));

    //是否有托盘值改变触发
    private static void OnHaveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as ConveyorLine).RefreshHaveStatus();

    #endregion Properties

    #region Constructors

    public ConveyorLine()
    {
        InitializeComponent();
        this.Background = Background ?? Brushes.DimGray;
        Cursor = Cursors.Hand; //小手
        //MouseLeftButtonDown += ConveyorLine_MouseLeftButtonDown;
        SizeChanged += ConveyorLine_SizeChanged;
        //this.Loaded += ConveyorLine_Loaded;
        //Task.Run(UIChange); //UI 变化
    }

    #endregion Constructors

    #region Event

    /// <summary>
    /// 重载鼠标左击时触发事件
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);
        //_eventAggregator.GetEvent<StationEvent>().Publish(SName);
        var command = Command;
        var parameter = CommandParameter;
        var target = CommandTarget;

        var routedCmd = command as RoutedCommand;
        if (routedCmd != null && routedCmd.CanExecute(parameter, target))
        {
            routedCmd.Execute(parameter, target);
        }
        else if (command != null && command.CanExecute(parameter))
        {
            command.Execute(parameter);
        }
    }

    private async void ConveyorLine_Loaded(object sender, RoutedEventArgs e)
    {
        await using HubConnection hubConnection = new HubConnectionBuilder().WithUrl(AddressManager.Address + AddressManager.StationHub).Build();
        hubConnection.On<string, YesNo>("ChangeStatus", async (sname, status) =>
        {
            await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (sname == SName)
                    if (status != HaveStatus) HaveStatus = status;
            }), System.Windows.Threading.DispatcherPriority.Background);
        });
        if (hubConnection.State != HubConnectionState.Connected)
        {
            await hubConnection.StartAsync();
            await hubConnection.InvokeAsync("InitalStatus", SName);
        }
    }

    /// <summary>
    /// 控件大小变化触发事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ConveyorLine_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        //清空重新加载
        this.LayoutCanvas.Children.Clear();
        ToolTip = $"输送线:{SName}";
        //实际宽小于高 - 认定为竖放标志
        verticalflag = LayoutCanvas.ActualWidth < LayoutCanvas.ActualHeight ? true : false;

        //左侧竖边
        leftline = new Rectangle();
        leftline.Width = verticalflag ? LayoutCanvas.ActualWidth / 10 : LayoutCanvas.ActualWidth / 20;
        leftline.Height = LayoutCanvas.ActualHeight;
        leftline.Fill = Background == Brushes.Transparent ? Brushes.DimGray : Background;
        LayoutCanvas.Children.Add(leftline);
        //右侧竖边
        rightline = new Rectangle();
        rightline.Width = verticalflag ? LayoutCanvas.ActualWidth / 10 : LayoutCanvas.ActualWidth / 20;
        rightline.Height = LayoutCanvas.ActualHeight;
        rightline.Fill = Background == Brushes.Transparent ? Brushes.DimGray : Background;
        rightline.Margin = new()
        {
            Left = LayoutCanvas.ActualWidth * (verticalflag ? 9 : 19) / (verticalflag ? 10 : 20)
        };
        LayoutCanvas.Children.Add(rightline);

        //上侧橫边
        topline = new Rectangle();
        topline.Width = this.LayoutCanvas.ActualWidth;
        topline.Height = verticalflag ? LayoutCanvas.ActualHeight / 20 : LayoutCanvas.ActualHeight / 10;
        topline.Fill = Background == Brushes.Transparent ? Brushes.DimGray : Background;
        LayoutCanvas.Children.Add(topline);
        //下侧橫边
        bottomline = new Rectangle();
        bottomline.Width = this.LayoutCanvas.ActualWidth;
        bottomline.Height = verticalflag ? LayoutCanvas.ActualHeight / 20 : LayoutCanvas.ActualHeight / 10;
        bottomline.Fill = Background == Brushes.Transparent ? Brushes.DimGray : Background;

        bottomline.Margin = new Thickness()
        {
            Top = this.LayoutCanvas.ActualHeight * (verticalflag ? 19 : 9) / (verticalflag ? 20 : 10)
        };
        LayoutCanvas.Children.Add(bottomline);

        //滚筒 间隔 3
        if (verticalflag)
        {//竖放输送线 滚筒摆放
            //计算 可以放的滚筒个数
            int rattlerCount = (int)(this.LayoutCanvas.ActualHeight / (this.LayoutCanvas.ActualHeight / 20 + 3));

            for (int i = 1; i < rattlerCount; i++)
            {
                this.LayoutCanvas.Children.Add(new Rectangle()
                {
                    Width = this.LayoutCanvas.ActualWidth - leftline.Width * 2,
                    Height = this.LayoutCanvas.ActualHeight / 20,
                    Fill = Brushes.White,
                    RadiusX = 2, //圆角
                    RadiusY = 2,
                    Margin = new()
                    {
                        Left = leftline.Width,
                        Top = this.LayoutCanvas.ActualHeight * i / 20 + i * 3,
                    }
                }); ;
            }
        }
        else
        {//横放输送线 滚筒摆放
            int rattlerCount = (int)(this.LayoutCanvas.ActualWidth / (this.LayoutCanvas.ActualWidth / 20 + 3));
            for (int i = 1; i < rattlerCount; i++)
            {
                this.LayoutCanvas.Children.Add(new Rectangle()
                {
                    Width = this.LayoutCanvas.ActualWidth / 20,
                    Height = this.LayoutCanvas.ActualHeight - topline.Height * 2,
                    Fill = Brushes.White,
                    RadiusX = 2,//圆角
                    RadiusY = 2,
                    Margin = new()
                    {
                        Top = topline.Height,
                        Left = this.LayoutCanvas.ActualWidth * i / 20 + i * 3
                    }
                });
            }
        }

        //托盘
        goods = new Rectangle();
        goods.Width = LayoutCanvas.ActualWidth > 20 ? 20 : LayoutCanvas.ActualWidth;
        goods.Height = LayoutCanvas.ActualHeight > 20 ? 20 : LayoutCanvas.ActualHeight;
        // goods.Fill = new SolidColorBrush(Color.FromRgb(0, 229, 255));
        goods.Fill = new SolidColorBrush(Color.FromRgb(11, 112, 253));
        double left = LayoutCanvas.ActualWidth - 20 > 0 ? LayoutCanvas.ActualWidth / 2 - 10 : 0;
        double top = LayoutCanvas.ActualHeight - 20 > 0 ? LayoutCanvas.ActualHeight / 2 - 10 : 0;
        goods.Margin = new()
        {
            Left = left,
            Top = top,
        };
        goods.Visibility = HaveStatus == YesNo.否 ? Visibility.Hidden : Visibility.Visible;
        LayoutCanvas.Children.Add(goods);
    }

    /// <summary>
    /// 鼠标点击将点击的输送线SName发布出去
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    //private void ConveyorLine_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => GlobalVariable.ea.GetEvent<StationEvent>().Publish(SName);

    /// <summary>
    /// 刷新是否有货/托盘
    /// </summary>
    public void RefreshHaveStatus() => Dispatcher.Invoke(new Action(delegate
    {
        goods.Visibility = HaveStatus == YesNo.否 ? Visibility.Hidden : Visibility.Visible;
    }));

    #endregion Event

    #region Animation

    //

    #endregion Animation
}